package com.magold.game.factory;

import java.util.List;

import org.andengine.entity.IEntity;
import org.andengine.entity.scene.Scene;
import org.andengine.extension.physics.box2d.PhysicsWorld;
import org.andengine.opengl.vbo.VertexBufferObjectManager;

import com.magold.circuit.CircuitBuilder;
import com.magold.circuit.ICircuit;
import com.magold.circuit.ICircuitPath;
import com.magold.circuit.module.CircuitModule;
import com.magold.io.ElementTranversalCallback;
import com.magold.io.XMLDataAccessor;
import com.magold.io.XMLReader;
import com.magold.level.EntityBuilder;
import com.magold.level.ILevel;
import com.magold.level.ILevel.CircuitParamProvider;
import com.magold.level.ILevelElementLoader;
import com.magold.texture.TextureFactory;

/**
 * 
 * @author Eternity
 *
 */
public class CircuitFactory implements ILevelElementLoader {
	
	@Override
	public boolean onLoadEntity(XMLReader pReader, ILevel pLoadingLevel) {
		final CircuitParamProvider moduleProvider = pLoadingLevel.getCircuitParamProvider();
		
		int bid = pReader.getInt("battery", -1);
		CircuitModule battery;
		if (bid >= 0) {
			battery = moduleProvider.findCircuitModule(bid);
		} else {
			battery = createDefaultBattery();
		}
		
		final CircuitBuilder builder = new CircuitBuilder(battery);
		pReader.traverseChildren(new ElementTranversalCallback() {
			@Override
			public boolean onAccessChild(XMLDataAccessor pDataAccessor) {
				int lid = pDataAccessor.getInt("left");
				CircuitModule lm = moduleProvider.findCircuitModule(lid);
				
				int rid = pDataAccessor.getInt("right");
				CircuitModule rm = moduleProvider.findCircuitModule(rid);

				String type = pDataAccessor.getNodeName();
				if (type.equals("direct_link")) {
					builder.link(lm, rm);
				} else {
					int pid = pDataAccessor.getInt("parallel");
					CircuitModule pm = moduleProvider.findCircuitModule(pid);
					
					if (type.equals("link_corner_left")) {
						builder.linkCornerAsLeft(lm, rm, pm);
					} else if (type.equals("link_corner_right")) {
						builder.linkCornerAsRight(lm, rm, pm);
					}
				}
					
				return true;
			}
		});
		
		pLoadingLevel.postBuilder(builder);
		pLoadingLevel.postBuilder(new EntityBuilder() {
			
			@Override
			public void build(Scene pScene, PhysicsWorld pWorld, VertexBufferObjectManager pManager) {
				List<IEntity> wires = builder.generateWires(TextureFactory.createImage("sprite/wire.png"), pManager);
				for (IEntity wire : wires) {
					pScene.attachChild(wire);
				}
			}
		});
		
		return false;
	}

	protected CircuitModule createDefaultBattery() {
		return new CircuitModule() {
			int mID;
			@Override
			public void setID(int pID) {
				mID = pID;
			}
			
			@Override
			public void onPathJoined(ICircuit pCircuit, ICircuitPath pPath) {
			}
			
			@Override
			public void onCurrentEnd() {
			}
			
			@Override
			public void onCurrentBegin() {
			}
			
			@Override
			public boolean isConnected() {
				return true;
			}
			
			@Override
			public int getID() {
				return mID;
			}

			@Override
			public float[] getWireInPosition() {
				return null;
			}

			@Override
			public float[] getWireOutPosition() {
				return null;
			}
		};
	}
	
}
